import '../models/period_model.dart';
import '../services/database_helper.dart';
import 'base_repository.dart';
import '../utils/date_utils.dart' as custom_date_utils;


class PeriodRepositoryImpl implements PeriodRepository {
  final DatabaseHelper _databaseHelper;

  PeriodRepositoryImpl(this._databaseHelper);

  @override
  Future<PeriodModel?> getById(int id) async {
    final db = await _databaseHelper.database;
    final maps = await db.query(
      DatabaseHelper.tablePeriod,
      where: '${DatabaseHelper.columnPeriodId} = ?',
      whereArgs: [id],
      limit: 1,
    );

    if (maps.isNotEmpty) {
      return _mapToPeriodModel(maps.first);
    }
    return null;
  }

  @override
  Future<List<PeriodModel>> getAll() async {
    final db = await _databaseHelper.database;
    final maps = await db.query(
      DatabaseHelper.tablePeriod,
      orderBy: '${DatabaseHelper.columnPeriodStart} DESC',
    );
    return maps.map((map) => _mapToPeriodModel(map)).toList();
  }

  @override
  Future<int> save(PeriodModel entity) async {
    final db = await _databaseHelper.database;
    return await db.insert(DatabaseHelper.tablePeriod, _toMap(entity));
  }

  @override
  Future<bool> update(PeriodModel entity) async {
    final db = await _databaseHelper.database;
    final rowsAffected = await db.update(
      DatabaseHelper.tablePeriod,
      _toMap(entity),
      where: '${DatabaseHelper.columnPeriodId} = ?',
      whereArgs: [entity.id ?? 0],
    );
    return rowsAffected > 0;
  }

  @override
  Future<bool> delete(int id) async {
    final db = await _databaseHelper.database;
    final rowsAffected = await db.delete(
      DatabaseHelper.tablePeriod,
      where: '${DatabaseHelper.columnPeriodId} = ?',
      whereArgs: [id],
    );
    return rowsAffected > 0;
  }

  @override
  Future<List<PeriodModel>> getByDateRange(DateTime startDate, DateTime endDate) async {
    final db = await _databaseHelper.database;
    final maps = await db.query(
      DatabaseHelper.tablePeriod,
      where: '${DatabaseHelper.columnPeriodStart} >= ? AND ${DatabaseHelper.columnPeriodEnd} <= ?',
      whereArgs: [
        custom_date_utils.DateUtils.formatDate(startDate),
        custom_date_utils.DateUtils.formatDate(endDate),
      ],
      orderBy: '${DatabaseHelper.columnPeriodStart} ASC',
    );
    return maps.map((map) => _mapToPeriodModel(map)).toList();
  }

  @override
  Future<PeriodModel?> getByDate(DateTime date) async {
    final db = await _databaseHelper.database;
    final maps = await db.query(
      DatabaseHelper.tablePeriod,
      where: '${DatabaseHelper.columnPeriodStart} = ?',
      whereArgs: [custom_date_utils.DateUtils.formatDate(date)],
      limit: 1,
    );

    if (maps.isNotEmpty) {
      return _mapToPeriodModel(maps.first);
    }
    return null;
  }

  @override
  Future<List<PeriodModel>> getCurrentMonthRecords() async {
    final now = DateTime.now();
    final firstDay = DateTime(now.year, now.month, 1);
    final lastDay = DateTime(now.year, now.month + 1, 0);
    return getByDateRange(firstDay, lastDay);
  }

  
  Map<String, dynamic> _toMap(PeriodModel period) {
    return {
      DatabaseHelper.columnPeriodStart: custom_date_utils.DateUtils.formatDate(period.date),
      DatabaseHelper.columnPeriodEnd: custom_date_utils.DateUtils.formatDate(period.date),
      DatabaseHelper.columnPeriodFlow: period.flowLevel,
      DatabaseHelper.columnPeriodNote: period.notes,
      DatabaseHelper.columnPeriodUserId: 1, // 假设默认用户ID为1
    };
  }

  PeriodModel _mapToPeriodModel(Map<String, dynamic> map) {
    final date = DateTime.parse(map[DatabaseHelper.columnPeriodStart] as String);
    final now = DateTime.now();
    final isToday = date.year == now.year && date.month == now.month && date.day == now.day;
    
    return PeriodModel(
      date: date,
      isPeriod: true, // 数据库中的记录都是经期记录
      isOvulation: false,
      isToday: isToday,
      isPredictedPeriod: false,
      isPossiblePeriod: false,
      notes: map[DatabaseHelper.columnPeriodNote] as String?,
      flowLevel: map[DatabaseHelper.columnPeriodFlow] as double?,
    );
  }

}